package com.sen.common.tags;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.sen.common.orm.PublicDao;
import com.sen.common.utils.spring.SpringUtils;
import com.sen.common.widget.form.Select;
import com.sen.common.widget.form.SelectOption;

/**
 * 下拉标签.
 * 
 * @author sen
 */
public abstract class AbstractSelectTag extends TagSupport {

	private static final long serialVersionUID = 9071073968567787481L;
	private static Logger log = Logger.getLogger(AbstractSelectTag.class);

	protected PublicDao publicDao;
	
	private String nullable = "YES";
	private String emptyOption = "";
	private String value = "";
	private String defaultValue = "";
	private String id;
	private String name;
	private String style;
	private String caption;
	private String className;

	private List<SelectOption> selectOptions;

	public AbstractSelectTag() {
		this("");
	}

	public AbstractSelectTag(String defaultSelectName) {
		this.name = defaultSelectName;
	}

	@Override
	public int doStartTag() throws JspException {
		try {
			selectOptions = new ArrayList<SelectOption>();

			publicDao = SpringUtils.getBean(pageContext.getServletContext(),
					"publicDao", PublicDao.class);

			initSettings();

			JspWriter out = pageContext.getOut();
			String html = buildSelectHtml();
			out.print(html);

			out.flush();
		} catch (Exception e) {
			log.warn("AbstractChoiceTag报错", e);
		}
		return SKIP_BODY;
	}

	/**
	 * 初始化默认的参数设置s
	 */
	protected void initSettings() {
		// empty!
	}

	private String buildSelectHtml() {
		Select select = new Select(id, name);
		if (BooleanUtils.toBoolean(nullable)) {
			select.emptyOption(emptyOption);
		}
		select.selected(getSelectedOption()).style(style).caption(caption)
				.className(className);
		addOptions();
		addOptionsTo(select);
		return select.toHtml();
	}

	private String getSelectedOption() {
		if (StringUtils.isEmpty(value)) {
			return defaultValue;
		}
		return value;
	}

	protected abstract void addOptions();

	protected void addOption(String value, String text) {
		selectOptions.add(new SelectOption(value, text));
	}

	protected void addOption(SelectOption option) {
		selectOptions.add(option);
	}

	private void addOptionsTo(Select select) {
		if (CollectionUtils.isEmpty(selectOptions)) {
			return;
		}
		for (SelectOption option : selectOptions) {
			select.option(option);
		}
	}

	public void setNullable(String nullable) {
		this.nullable = nullable;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setEmptyOption(String emptyOption) {
		this.emptyOption = emptyOption;
	}

	public void setStyle(String style) {
		this.style = style;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	}

	public void setCaption(String caption) {
		this.caption = caption;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getValue() {
		return value;
	}
}
